package com.easymin.weixin.common.api;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.easymin.weixin.common.DataGrid;
import com.easymin.weixin.common.Distance;
import com.easymin.weixin.common.SignHelper;
import com.easymin.weixin.controller.v4.ResultTransport;
import com.easymin.weixin.controller.v5.utils.ResultV5;
import com.easymin.weixin.entity.Order;
import com.easymin.weixin.entity.OrderGrab;
import com.easymin.weixin.entity.OrderMemo;
import com.easymin.weixin.entity.OrderReview;
import com.easymin.weixin.entity.OrderType;
import com.easymin.weixin.entity.area.Area;
import com.easymin.weixin.entity.area.ChargeStartTime;
import com.easymin.weixin.entity.passenger.Passenger;
import com.google.common.collect.Lists;

/**
 * Created by shine on 15/10/3.
 */
@SuppressWarnings("all")
@Component
public class ErrandApi {
  
  private static final Logger logger = LoggerFactory.getLogger(ErrandApi.class);

  @Value("${module.errand.url}")
  private String errandApiGateway;

  @Value("${module.errand.appId}")
  private String errandAppId;

  @Value("${module.errand.appKey}")
  private String errandAppKey;

  @Autowired
  private RestTemplate restTemplate;
  
  /**
   * 创建订单.
   */
  
  public static final String CREATE =
      "api/orders.json?title={title}&content={content}&deliverTime={deliverTime}"
      + "&deliverAddress={deliverAddress}&deliverLat={deliverLat}&deliverLng={deliverLng}"
      + "&passengerId={passengerId}&passengerName={passengerName}&passengerPhone={passengerPhone}"
      + "&channelName={channelName}&companyId={companyId}&companyName={companyName}"
      + "&operator={operator}&errandFixPrice={errandFixPrice}&appKey={appKey}"
      + "&appId={appId}&sign={sign}&shouldPay={shouldPay}";

  /**
   * 保存图片对象.
   */
  public static final String SAVEIMG =
      "api/orderimg.json?orderId={orderId}&source={source}"
      + "&imgs={imgs}&appKey={appKey}&appId={appId}&sign={sign}";

  /**
   * 根据ID查询订单.
   */
  public static final String FIND_BY_ID =
      "api/orders/findOne.json?orderId={orderId}&appKey={appKey}&appId={appId}&sign={sign}";
  /**
   * 添加抢单记录.
   */
  public static final String FIND_ADD_GRAB =
      "api/orderGrab/create.json?orderId={orderId}&employId={employId}&employName={employName}"
      + "&employPhone={employPhone}&employCompanyId={employCompanyId}&distance={distance}"
      + "&appKey={appKey}&appId={appId}&sign={sign}";
  /**
   * 设置抢单记录为成功状态.
   */
  public static final String FIND_UPDATE_GRAB =
      "api/orderGrab/update.json?grabId={grabId}&appKey={appKey}&appId={appId}&sign={sign}";
  /**
   * 根据订单Id查询订单抢单记录.
   */
  public static final String FIND_GRAB =
      "api/orderGrab/findGrabs.json?orderId={orderId}&appKey={appKey}&appId={appId}&sign={sign}";
  /**
   * 催促订单进度.
   */
  public static final String HASTEN_ORDER =
      "api/orders/hasten.json?orderId={orderId}&appKey={appKey}&appId={appId}&sign={sign}";

  /**
   * 根据状态查询订单列表.
   */
  public static final String FIND_BY_STATUS =
      "api/orders/findByStatus.json?passengerId={passengerId}&status={status}&orderby={orderby}"
      + "&page={page}&rows={rows}&appKey={appKey}&appId={appId}&sign={sign}";
  /**
   * 司机端 最新订单(没有派单的)status=0.
   */
  public static final String FIND_NEW_ORDER =
      "api/orders.json?appKey={appKey}&appId={appId}&sign={sign}&status={status}&orderby={orderby}"
      + "&page={page}&rows={rows}";
  /**
   * 司机端 最离我最近(没有派单的)status=0.
   */
  public static final String FIND_NEAR_ORDER =
      "api/orders.json?appKey={appKey}&appId={appId}&sign={sign}&longitude={longitude}"
      + "&latitude={latitude}&distance={distance}&status={status}&page={page}&rows={rows}";
  /**
   * 司机当前任务(已接单,已执行但未完成的).
   */
  public static final String FIND_MY_WORK =
      "api/orders.json?appKey={appKey}&appId={appId}&sign={sign}&employId={employId}"
      + "&status={status}&orderby={orderby}&page={page}&rows={rows}";

  /**
   * 获取司机评分.
   */
  public static final String EMPLOY_SCORE =
      "api/orderReview/getReview.json?orderId={orderId}&appKey={appKey}&appId={appId}&sign={sign}";
  /**
   * 修改订单状态为接单.
   */
  public static final String UPDATE_STATUS_JIEDAN =
      "api/orders/update.json?appKey={appKey}&appId={appId}&sign={sign}&orderId={orderId}"
      + "&action={action}&employId={employId}&employName={employName}&employPhone={employPhone}"
      + "&employCompanyId={employCompanyId}&operator={operator}";
  /**
   * 修改订单状态为销单.
   */
  public static final String UPDATE_STATUS_CANCEL =
      "api/orders/update.json?appKey={appKey}&appId={appId}&sign={sign}&orderId={orderId}"
      + "&action={action}&operator={operator}&cause={cause}";
  /**
   * 修改订单状态为拒单.
   */
  public static final String UPDATE_STATUS_REFUSE =
      "api/orders/update.json?appKey={appKey}&appId={appId}&sign={sign}&orderId={orderId}"
      + "&employId={employId}&action={action}&operator={operator}&cause={cause}";
  /**
   * 修改订单为正在执行.
   */
  public static final String UPDATE_STATUS_RUN =
      "api/orders/update.json?appKey={appKey}&appId={appId}&sign={sign}&orderId={orderId}"
      + "&action={action}&operator={operator}";
  /**
   * 修改订单为已完成.
   */
  public static final String UPDATE_STATUS_FINISH =
      "api/orders/update.json?appKey={appKey}&appId={appId}&sign={sign}&orderId={orderId}"
      + "&action={action}&operator={operator}";
  /**
   * 评价订单.
   */
  public static final String ORDER_REVIEW =
      "api/orderReview.json?appKey={appKey}&appId={appId}&sign={sign}&orderId={orderId}"
      + "&score={score}&content={content}";
  /**
   * 收费信息.
   */
  public static final String PRICE_INFO =
      "api/errandPay/findErrandPay.json?appKey={appKey}&appId={appId}&sign={sign}"
      + "&city={city}&acKey={acKey}";
  /**
   * 查询统计客户端的三个列表订单数量.
   */
  public static final String QUERY_ORDERS =
      "api/orders/queryOrders.json?appKey={appKey}&appId={appId}"
      + "&sign={sign}&passengerId={passengerId}";

  /**
   * 查询三个司机端列表的订单数量.
   */
  public static final String QUERY_COUNTS =
      "api/orders/queryCount.json?appKey={appKey}&appId={appId}&sign={sign}"
      + "&employId={employId}&longitude={longitude}&latitude={latitude}&distance={distance}";
  /**
   * v2查询跑腿类型.
   */
  public static final String QUERY_ORDER_TYPE =
      "v2/orderType.json?companyId={companyId}&appId={appId}&sign={sign}&appKey={appKey}";
  /**
   * V2查询一个类型.
   */
  public static final String QUERY_ONE_TYPE =
      "v2/orderType/findOrderType.json?orderTypeId={orderTypeId}&appId={appId}"
      + "&sign={sign}&appKey={appKey}";
  /**
   * V2保存跑腿订单.
   */
  public static final String SAVE_ORDER = "v2/api/orders/create";
  /**
   * v2查询单个跑腿订单.
   */
  public static final String FIND_ONE_ORDER =
      "v2/api/orders/findOne.json?orderId={orderId}&appKey={appKey}&appId={appId}&sign={sign}";
  /**
   * v2根据状态查询订单列表.
   */
  public static final String FIND_BY_STATUS_V2 =
      "v2/api/orders.json?passengerId={passengerId}&status={status}"
      + "&orderby={orderby}&page={page}&rows={rows}&appKey={appKey}&appId={appId}&sign={sign}";
  /**
   * V2评价订单.
   */
  public static final String ORDER_REVIEW_V2 = "v2/api/orders/orderReview";
  /**
   * V2催单.
   */
  public static final String HASTEN_ORDER_V2 =
      "v2/api/orders/hasten.json?orderId={orderId}&appKey={appKey}&appId={appId}&sign={sign}";
  /**
   * V2销单.
   */
  public static final String UPDATE_STATUS_CANCEL_V2 =
      "v2/api/orders/update.json?appKey={appKey}&appId={appId}&sign={sign}&orderId={orderId}"
      + "&action={action}&operator={operator}&cause={cause}";
  /**
   * V2接单.
   */
  public static final String UPDATE_STATUS_JIEDAN_V2 =
      "v2/api/orders/jiedan.json?appKey={appKey}&appId={appId}&sign={sign}&orderId={orderId}"
      + "&employId={employId}&employName={employName}"
      + "&employPhone={employPhone}&operator={operator}";
  /**
   * V2抢单.
   */
  public static final String GRAB_ORDER_V2 =
      "v2/api/orders/grabOrder.json?appKey={appKey}&appId={appId}&sign={sign}&orderId={orderId}"
      + "&employId={employId}&employName={employName}"
      + "&employPhone={employPhone}&operator={operator}";
  /**
   * V2司机当前任务(已接单,已执行但未完成的).
   */
  public static final String FIND_MY_WORK_V2 =
      "v2/api/orders.json?appKey={appKey}&appId={appId}&sign={sign}&employId={employId}"
          + "&status={status}&orderby={orderby}&page={page}&rows={rows}";
  /**
   * V2司机查询已完成订单.
   */
  public static final String FIND_FINISH_ORDER_V2 =
      "v2/api/orders.json?appKey={appKey}&appId={appId}&sign={sign}&employId={employId}"
          + "&status={status}&orderby={orderby}&page={page}&rows={rows}";
  /**
   * V4查询跑腿类型.
   */
  public static final String QUERY_TYPE_V4 = "v4/api/orders/queryTypeV4?appKey={appKey}";

  /**
   * V5查询跑腿类型.
   */
  public static final String QUERY_TYPE_V5 = "v4/api/orders/queryTypeV4?appKey={appKey}";

  /**
   * V4接单.
   */
  public static final String UPDATE_JIEDAN_V4 = "v4/api/orders/jiedan";
  /**
   * V4拒接订单.
   */
  public static final String UPDATE_REFUSE_V4 = "v4/api/orders/refuse";
  /**
   * V4执行订单.
   */
  public static final String UPDATE_RUN_V4 = "v4/api/orders/run";
  /**
   * V4查询单个订单.
   */
  public static final String FIND_ONE_ORDER_V4 =
      "v4/api/orders/findOne.json?orderId={orderId}&appKey={appKey}&appId={appId}&sign={sign}";
  /**
   * V4添加抢单记录.
   */
  public static final String ADDGRAB_V4 = "v4/api/orders/tograbOrder";
  /**
   * V4抢单指派订单.
   */
  public static final String GRAB_ORDER_V4 = "v4/api/orders/grabOrder";
  /**
   * V4销单.
   */
  public static final String CANCEL_V4 = "v4/api/orders/cancel";
  /**
   * V4司机补单接口.
   */
  public static final String SAVE_ORDER_V4 = "v4/api/orders/create";
  /**
   * V4查询单个类型.
   */
  public static final String QUERY_ONE_TYPE_V4 =
      "v4/api/orders/queryOneType.json?orderTypeId={orderTypeId}&appKey={appKey}";
  /**
   * V4修改结束地点.
   */
  public static final String UPDATE_TOPLACE_V4 = "v4/api/orders/updateToPlace";
  
  /**
   * 查询未完成订单数量.
   */
  
  public static final String COUNT_RUNNINGS =
      "v2/api/orders/countRunning.json?passengerId={passengerId}"
      + "&appKey={appKey}&appId={appId}&sign={sign}";
  
  /**
   * 查询未支付订单.
   */
  public static final String COUNT_NOTPAYAMOUNTS =
      "v2/api/orders/countByPassengerId.json?passengerId={passengerId}"
      + "&appKey={appKey}&appId={appId}&sign={sign}";
  
  /**
   * 查询未完成订单数量数量
   */
  public static final String COUNT_NOTFINISHEDAMOUNTS =
      "v4/api/orders/queryRunOrder.json?passengerId={passengerId}"
      + "&appKey={appKey}";
  

  /**
   * 查询未完成订单.
   */
  
  public static final String FIND_RUNNING =
      "api/orders/orderlist.json?passengerId={passengerId}&allstatus={allstatus}&appKey={appKey}";

  /**
   * 创建跑腿订单.
   */
  
  public JSONObject create(Order order, Passenger passenger, String appKey) throws Exception {
    String url = buildApi(CREATE);
    Map<String, String> kv = new HashMap<>();
    kv.put("title", order.getTitle());
    kv.put("content", order.getContent());
    kv.put("deliverTime", String.valueOf(order.getDeliverTime().getTime()));
    kv.put("deliverAddress", order.getDeliverAddress());
    kv.put("deliverLat", String.valueOf(order.getDeliverLat()));
    kv.put("deliverLng", String.valueOf(order.getDeliverLng()));
    kv.put("passengerId", String.valueOf(passenger.getId()));
    kv.put("passengerName", passenger.getName());
    kv.put("passengerPhone", passenger.getPhone());
    kv.put("channelName", order.getChannelName());
    if (null == order.getCompanyId() || StringUtils.isBlank(order.getCompanyName())) {
      kv.put("companyId", String.valueOf(passenger.getCompanyId()));
      kv.put("companyName", passenger.getCompanyName());
    } else {
      kv.put("companyId", String.valueOf(order.getCompanyId()));
      kv.put("companyName", order.getCompanyName());
    }
    kv.put("operator", passenger.getName());
    kv.put("errandFixPrice", String.valueOf(order.getErrandFixPrice()));
    kv.put("shouldPay", order.getShouldPay() != null ? String.valueOf(order.getShouldPay()) : null);
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    // 新增的参数--------
    if (order.getStartTime() != null) {
      kv.put("startTime", String.valueOf(order.getStartTime().getTime()));
      url += "&startTime={startTime}";
    }
    if (StringUtils.isNotBlank(order.getStartPhone())) {
      kv.put("startPhone", order.getStartPhone());
      url += "&startPhone={startPhone}";
    }
    if (StringUtils.isNotBlank(order.getEndPhone())) {
      kv.put("endPhone", order.getEndPhone());
      url += "&endPhone={endPhone}";
    }
    if (StringUtils.isNotBlank(order.getStartAddress())) {
      kv.put("startAddress", order.getStartAddress());
      url += "&startAddress={startAddress}";
    }
    if (order.getStartLat() != null && order.getStartLat() != 0) {
      kv.put("startLat", String.valueOf(order.getStartLat()));
      url += "&startLat={startLat}";
    }
    if (order.getStartLng() != null && order.getStartLng() != 0) {
      kv.put("startLng", String.valueOf(order.getStartLng()));
      url += "&startLng={startLng}";
    }
    if (StringUtils.isNotBlank(order.getOrderType())) {
      kv.put("orderType", order.getOrderType());
      url += "&orderType={orderType}";
    }
    if (order.getStartPrice() != null && order.getStartPrice() != 0) {
      kv.put("startPrice", String.valueOf(order.getStartPrice()));
      url += "&startPrice={startPrice}";
    }
    if (order.getMileagePrice() != null && order.getMileagePrice() != 0) {
      kv.put("mileagePrice", String.valueOf(order.getMileagePrice()));
      url += "&mileagePrice={mileagePrice}";
    }
    if (order.getTravelTimePrice() != null && order.getTravelTimePrice() != 0) {
      kv.put("travelTimePrice", String.valueOf(order.getTravelTimePrice()));
      url += "&travelTimePrice={travelTimePrice}";
    }
    if (order.getMileage() != null && order.getMileage() != 0) {
      kv.put("mileage", String.valueOf(order.getMileage()));
      url += "&mileage={mileage}";
    }
    if (order.getTravelTime() != null && order.getTravelTime() != 0) {
      kv.put("travelTime", String.valueOf(order.getTravelTime()));
      url += "&travelTime={travelTime}";
    }

    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Lists.newArrayList(MediaType.APPLICATION_JSON));

    ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, null, String.class, kv);

    if (responseEntity.getStatusCode().is2xxSuccessful()) {

      JSONObject json = (JSONObject) JSON.parse(responseEntity.getBody());
      return json;

    }
    return null;
  }
  
  /**
   * 保存跑腿图片.
   */
  
  public int saveImgs(Long orderId, String channelName, String imgs, String appKey) {
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderId", String.valueOf(orderId));
    kv.put("source", channelName);
    kv.put("imgs", imgs);
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    ResponseEntity<String> responseEntity =
        restTemplate.postForEntity(buildApi(SAVEIMG), null, String.class, kv);
    if (responseEntity.getStatusCode().is2xxSuccessful()) {
      JSONObject json = (JSONObject) JSON.parse(responseEntity.getBody());
      int insert = json.getIntValue("insert");
      return insert;
    } else {
      return -1;
    }
  }


  /**
   * 根据主键查询订单信息.
   */
  
  public Order findById(Long orderId, String appKey) throws Exception {

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderId", String.valueOf(orderId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(FIND_BY_ID), String.class, kv);

    JSONObject jo = JSON.parseObject(result);
    Order order = null;
    if (jo.getIntValue("code") == 0) {
      order = jo.getObject("data", Order.class);
    }

    return order;
  }

  /**
   * 添加抢单记录.
   */
  public JSONObject addOrderGrab(Long orderId, Long employId, String employName,
      String employPhone, Long employCompanyId, Double distance, String appKey) {
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderId", String.valueOf(orderId));
    kv.put("employId", String.valueOf(employId));
    kv.put("employName", employName);
    kv.put("employPhone", employPhone);
    kv.put("employCompanyId", String.valueOf(employCompanyId));
    kv.put("distance", String.valueOf(distance));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    ResponseEntity<String> responseEntity =
        restTemplate.postForEntity(buildApi(FIND_ADD_GRAB), null, String.class, kv);
    if (responseEntity.getStatusCode().is2xxSuccessful()) {

      JSONObject json = (JSONObject) JSON.parse(responseEntity.getBody());
      return json;
    }
    return null;

  }

  /**
   * 设置抢单记录为成功状态.
   */
  public JSONObject updateOrderGrab(Long grabId, String appKey) {
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("grabId", String.valueOf(grabId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    ResponseEntity<String> responseEntity =
        restTemplate.postForEntity(buildApi(FIND_UPDATE_GRAB), null, String.class, kv);
    if (responseEntity.getStatusCode().is2xxSuccessful()) {
      return (JSONObject) JSON.parse(responseEntity.getBody());
    }
    return null;

  }

  /**
   * 查询订单抢单记录.
   */

  public List<OrderGrab> findOrderGrab(Long orderId, String appKey) {
    List<OrderGrab> list = new ArrayList<OrderGrab>();
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderId", String.valueOf(orderId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(FIND_GRAB), String.class, kv);
    JSONObject object = JSON.parseObject(result);
    if (object.getIntValue("code") == 0) {
      JSONArray jsonArray = object.getJSONArray("data");
      list = JSON.parseArray(jsonArray.toString(), OrderGrab.class);
    }

    return list;
  }

  /**
   * 催一下订单进度.
   */
  public String hasten(Long orderId, String appKey) {
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderId", String.valueOf(orderId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);
    String result = restTemplate.getForObject(buildApi(HASTEN_ORDER), String.class, kv);
    JSONObject jo = JSON.parseObject(result);

    if (jo.getIntValue("code") == 0) {
      return "success";
    } else {
      return "fail";
    }
  }

  /**
   * 客户端 根据状态查询订单.
   */
  public DataGrid<Map<String, Object>> findByStatus(Long passengerId, Integer page, Integer rows,
      String status, String appKey) throws Exception {
    DataGrid<Map<String, Object>> dataGrid = new DataGrid<Map<String, Object>>();
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("passengerId", String.valueOf(passengerId));
    kv.put("status", status);
    kv.put("orderby", "created desc");
    kv.put("page", String.valueOf(page));
    kv.put("rows", String.valueOf(rows));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    ResponseEntity<String> responseEntity =
        restTemplate.postForEntity(buildApi(FIND_BY_STATUS), null, String.class, kv);
    JSONObject object = JSON.parseObject(responseEntity.getBody());
    int code = object.getIntValue("code");
    List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
    if (code == 0) {

      JSONObject json = object.getJSONObject("data");
      long total = json.getLong("total");

      dataGrid.setTotal(total);
      List<Order> list = new ArrayList<Order>();

      JSONArray jsonArray = json.getJSONArray("rows");
      list = JSON.parseArray(jsonArray.toString(), Order.class);
      for (Order order : list) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orderId", order.getId());
        map.put("orderNo", order.getOrderNo());
        map.put("title", order.getTitle());
        map.put("content", order.getContent());
        map.put("deliverTime", order.getDeliverTime().getTime());
        map.put("deliverAddress", order.getDeliverAddress());
        map.put("deliverLat", order.getDeliverLat());
        map.put("deliverLng", order.getDeliverLng());
        map.put("status", order.getStatus());
        map.put("shouldPay", order.getShouldPay());
        map.put("errandFixPrice", order.getErrandFixPrice());
        map.put("passengerId", order.getPassengerId());
        map.put("passengerName", order.getPassengerName());
        map.put("passengerPhone", order.getPassengerPhone());
        map.put("companyId", order.getCompanyId());
        map.put("companyName", order.getCompanyName());
        map.put("review", order.getReview());
        map.put("employName", order.getEmployName());
        map.put("employPhone", order.getEmployPhone());
        map.put("lasturge", order.getLasturge().getTime());
        Long employId = order.getEmployId();
        map.put("employId", employId);
        // 订单的评分和评价内容
        OrderReview orderReview = order.getOrderReview();
        if (orderReview != null) {
          map.put("score", orderReview.getScore());
          map.put("reviewContent", orderReview.getContent());
        }

        map.put("channelName", order.getChannelName());
        map.put("orderType", order.getOrderType());
        map.put("imgs", order.getImgs());// 多张图片地址
        map.put("startPhone", order.getStartPhone());
        map.put("endPhone", order.getEndPhone());
        map.put("startAddress", order.getStartAddress());
        map.put("startTime", order.getStartTime() != null ? order.getStartTime().getTime() : null);
        map.put("startLat", order.getStartLat());
        map.put("startLng", order.getStartLng());
        map.put("realPay", order.getRealPay());
        listMap.add(map);
      }
    }
    dataGrid.setRows(listMap);

    return dataGrid;
  }

  /**
   * 司机端 最新订单(没有派单的)status=0.
   */
  public DataGrid<Map<String, Object>> findNewOrder(Integer page, Integer rows, String appKey) {
    DataGrid<Map<String, Object>> dataGrid = new DataGrid<Map<String, Object>>();

    List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("page", String.valueOf(page));
    kv.put("rows", String.valueOf(rows));
    kv.put("orderby", "created desc");
    kv.put("status", "newOrder");
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(FIND_NEW_ORDER), String.class, kv);
    JSONObject object = JSON.parseObject(result);

    int code = object.getIntValue("code");
    if (code == 0) {
      JSONObject json = object.getJSONObject("data");
      long total = json.getLong("total");
      dataGrid.setTotal(total);

      List<Order> list = new ArrayList<Order>();

      JSONArray jsonArray = json.getJSONArray("rows");
      list = JSON.parseArray(jsonArray.toString(), Order.class);
      for (Order order : list) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orderId", order.getId());
        map.put("orderNo", order.getOrderNo());
        map.put("title", order.getTitle());
        map.put("content", order.getContent());
        map.put("deliverTime", order.getDeliverTime().getTime());
        map.put("deliverAddress", order.getDeliverAddress());
        map.put("deliverLat", order.getDeliverLat());
        map.put("deliverLng", order.getDeliverLng());
        map.put("status", order.getStatus());
        map.put("passengerId", order.getPassengerId());
        map.put("passengerName", order.getPassengerName());
        map.put("passengerPhone", order.getPassengerPhone());
        map.put("companyId", order.getCompanyId());
        map.put("companyName", order.getCompanyName());
        map.put("shouldPay", order.getShouldPay());
        map.put("errandFixPrice", order.getErrandFixPrice());

        map.put("channelName", order.getChannelName());
        map.put("orderType", order.getOrderType());
        map.put("imgs", order.getImgs());// 多张图片地址
        map.put("startPhone", order.getStartPhone());
        map.put("endPhone", order.getEndPhone());
        map.put("startAddress", order.getStartAddress());
        map.put("startTime", order.getStartTime() != null ? order.getStartTime().getTime() : null);
        map.put("startLat", order.getStartLat());
        map.put("startLng", order.getStartLng());
        listMap.add(map);
      }
    }
    dataGrid.setRows(listMap);
    return dataGrid;
  }

  /**
   * 司机端 查询附近的新订单(status=0).
   */
  public DataGrid<Map<String, Object>> findNearOrder(Double longitude, Double latitude,
      Double distance, Integer page, Integer rows, String appKey) {

    DataGrid<Map<String, Object>> dataGrid = new DataGrid<Map<String, Object>>();

    List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("longitude", String.valueOf(longitude));
    kv.put("latitude", String.valueOf(latitude));
    kv.put("distance", String.valueOf(distance));
    kv.put("page", String.valueOf(page));
    kv.put("rows", String.valueOf(rows));
    kv.put("status", "newOrder");
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(FIND_NEAR_ORDER), String.class, kv);
    JSONObject object = JSON.parseObject(result);

    int code = object.getIntValue("code");
    if (code == 0) {
      JSONObject json = object.getJSONObject("data");
      long total = json.getLong("total");
      dataGrid.setTotal(total);

      List<Order> list = new ArrayList<Order>();
      JSONArray jsonArray = json.getJSONArray("rows");
      list = JSON.parseArray(jsonArray.toString(), Order.class);
      for (int i = 0; i < list.size(); i++) {
        Order order = list.get(i);
        Double length =
            Distance.doubleVal(order.getStartLat(), order.getStartLng(), latitude, longitude);
        if (length > 0 && length <= 1) {
          BigDecimal decimal = new BigDecimal(1000 * length);
          BigDecimal abs = decimal.abs(new MathContext(3));
          String str = abs.intValue() + "米";
          order.setDistanceStr(str);
          order.setDistance(new BigDecimal(length).abs(new MathContext(3)).doubleValue());
        } else if (length > 1) {
          BigDecimal decimal = new BigDecimal(length);
          if (length <= 10) {
            BigDecimal abs = decimal.abs(new MathContext(2));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(2)).doubleValue());
          } else if (length > 10 && length < 100) {
            BigDecimal abs = decimal.abs(new MathContext(3));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(3)).doubleValue());
          } else if (length > 100 && length <= 1000) {
            BigDecimal abs = decimal.abs(new MathContext(4));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(4)).doubleValue());
          } else {
            BigDecimal abs = decimal.abs(new MathContext(5));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(5)).doubleValue());
          }

        }
      }
      // 排序(根据该司机的位置和订单的交付地址的距离由近到远排序).....
      for (int i = 0; i < list.size(); i++) {
        Order order = list.get(i);
        Double dis = order.getDistance();
        for (int j = 0; j < list.size(); j++) {
          Order ord = list.get(j);
          Double d2 = ord.getDistance();
          if (dis < d2) {
            Order temp = list.get(i);
            list.set(i, ord);
            list.set(j, temp);
          }
        }
      }
      // 排序.....结束....
      for (Order order : list) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orderId", order.getId());
        map.put("orderNo", order.getOrderNo());
        map.put("title", order.getTitle());
        map.put("content", order.getContent());
        map.put("deliverTime", order.getDeliverTime() != null ? order.getDeliverTime().getTime()
            : null);
        map.put("deliverAddress", order.getDeliverAddress());
        map.put("deliverLat", order.getDeliverLat());
        map.put("deliverLng", order.getDeliverLng());
        map.put("status", order.getStatus());
        map.put("passengerId", order.getPassengerId());
        map.put("passengerName", order.getPassengerName());
        map.put("passengerPhone", order.getPassengerPhone());
        map.put("distance", order.getDistance());
        map.put("distanceStr", order.getDistanceStr());
        map.put("companyId", order.getCompanyId());
        map.put("companyName", order.getCompanyName());
        map.put("shouldPay", order.getShouldPay());
        map.put("errandFixPrice", order.getErrandFixPrice());

        map.put("channelName", order.getChannelName());
        map.put("orderType", order.getOrderType());
        map.put("imgs", order.getImgs());// 多张图片地址
        map.put("startPhone", order.getStartPhone());
        map.put("endPhone", order.getEndPhone());
        map.put("startAddress", order.getStartAddress());
        map.put("startTime", order.getStartTime() != null ? order.getStartTime().getTime() : 0);
        map.put("startLat", order.getStartLat());
        map.put("startLng", order.getStartLng());
        map.put("mileage", order.getMileage());
        map.put("travelTime", order.getTravelTime());
        map.put("startPrice", order.getStartPrice());
        map.put("mileagePrice", order.getMileagePrice());
        map.put("travelTimePrice", order.getTravelTimePrice());
        listMap.add(map);
      }
    }
    dataGrid.setRows(listMap);
    return dataGrid;
  }

  /**
   * 司机当前任务(已接单,已执行但未完成的).
   */
  
  public DataGrid<Map<String, Object>> findMyWork(Long employId, 
      Double longitude, Double latitude, Integer page, Integer rows, String appKey) {
    DataGrid<Map<String, Object>> dataGrid = new DataGrid<Map<String, Object>>();

    List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();

    Map<String, String> kv = new HashMap<String, String>();
    String url = buildApi(FIND_MY_WORK);
    kv.put("employId", String.valueOf(employId));
    kv.put("page", String.valueOf(page));
    kv.put("rows", String.valueOf(rows));
    kv.put("orderby", "status asc,deliverTime desc");
    kv.put("status", "myWork");
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    if (longitude != null && longitude != 0) {
      kv.put("longitude", String.valueOf(longitude));
      url += "&longitude={longitude}";
    }
    if (latitude != null && latitude != 0) {
      kv.put("latitude", String.valueOf(latitude));
      url += "&latitude={latitude}";
    }
    if (longitude != null && latitude != null) {
      kv.put("distance", String.valueOf(10000));
      url += "&distance={distance}";
    }
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);
    String result = restTemplate.getForObject(url, String.class, kv);
    JSONObject object = JSON.parseObject(result);

    int code = object.getIntValue("code");
    if (code == 0) {
      JSONObject json = object.getJSONObject("data");
      long total = json.getLong("total");
      dataGrid.setTotal(total);

      List<Order> list = new ArrayList<Order>();
      JSONArray jsonArray = json.getJSONArray("rows");
      list = JSON.parseArray(jsonArray.toString(), Order.class);

      for (int i = 0; i < list.size(); i++) {
        Order order = list.get(i);
        Double length =
            Distance.doubleVal(order.getStartLat(), order.getStartLng(), latitude, longitude);
        if (length > 0 && length <= 1) {
          BigDecimal decimal = new BigDecimal(1000 * length);
          BigDecimal abs = decimal.abs(new MathContext(3));
          String str = abs.intValue() + "米";
          order.setDistanceStr(str);
          order.setDistance(new BigDecimal(length).abs(new MathContext(3)).doubleValue());
        } else if (length > 1) {
          BigDecimal decimal = new BigDecimal(length);
          if (length <= 10) {
            BigDecimal abs = decimal.abs(new MathContext(2));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(2)).doubleValue());
          } else if (length > 10 && length < 100) {
            BigDecimal abs = decimal.abs(new MathContext(3));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(3)).doubleValue());
          } else if (length > 100 && length <= 1000) {
            BigDecimal abs = decimal.abs(new MathContext(4));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(4)).doubleValue());
          } else {
            BigDecimal abs = decimal.abs(new MathContext(5));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(5)).doubleValue());
          }

        }
      }
      // 排序(根据该司机的位置和订单的交付地址的距离由近到远排序).....
      for (int i = 0; i < list.size(); i++) {
        Order order = list.get(i);
        Double dis = order.getDistance();
        for (int j = 0; j < list.size(); j++) {
          Order ord = list.get(j);
          Double d2 = ord.getDistance();
          if (dis < d2) {
            Order temp = list.get(i);
            list.set(i, ord);
            list.set(j, temp);
          }
        }
      }
      // 排序.....结束....

      for (Order order : list) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orderId", order.getId());
        map.put("orderNo", order.getOrderNo());
        map.put("title", order.getTitle());
        map.put("content", order.getContent());
        map.put("deliverTime", order.getDeliverTime() != null ? order.getDeliverTime().getTime()
            : null);
        map.put("deliverAddress", order.getDeliverAddress());
        map.put("deliverLat", order.getDeliverLat());
        map.put("deliverLng", order.getDeliverLng());
        map.put("status", order.getStatus());
        map.put("passengerId", order.getPassengerId());
        map.put("passengerName", order.getPassengerName());
        map.put("passengerPhone", order.getPassengerPhone());
        map.put("companyId", order.getCompanyId());
        map.put("companyName", order.getCompanyName());
        map.put("shouldPay", order.getShouldPay());
        map.put("errandFixPrice", order.getErrandFixPrice());
        map.put("employName", order.getEmployName());
        map.put("employPhone", order.getEmployPhone());
        StringBuilder sb = new StringBuilder();
        sb.append("\n");
        for (OrderMemo o : order.getMemoList()) {
          sb.append(o.getMemo() + "\n");
        }
        map.put("memoStr", sb.toString());

        map.put("channelName", order.getChannelName());
        map.put("orderType", order.getOrderType());
        map.put("imgs", order.getImgs());// 多张图片地址
        map.put("startPhone", order.getStartPhone());
        map.put("endPhone", order.getEndPhone());
        map.put("startAddress", order.getStartAddress());
        map.put("startTime", order.getStartTime() != null ? order.getStartTime().getTime() : null);
        map.put("startLat", order.getStartLat());
        map.put("startLng", order.getStartLng());
        map.put("distance", order.getDistance());
        map.put("distanceStr", order.getDistanceStr());
        map.put("mileage", order.getMileage());
        map.put("travelTime", order.getTravelTime());
        map.put("startPrice", order.getStartPrice());
        map.put("mileagePrice", order.getMileagePrice());
        map.put("travelTimePrice", order.getTravelTimePrice());

        listMap.add(map);
      }

    }
    dataGrid.setRows(listMap);

    return dataGrid;
  }

  /**
   * 查询统计客户端的三个列表订单数量.
   */
  
  public Map<String, Object> queryOrders(Long passengerId, String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();

    Map<String, String> kv = new HashMap<String, String>();

    kv.put("passengerId", String.valueOf(passengerId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(QUERY_ORDERS), String.class, kv);
    JSONObject jo = JSON.parseObject(result);
    int code = jo.getIntValue("code");
    if (code == 0) {
      JSONObject data = jo.getJSONObject("data");
      Long present = data.getLong("present");
      Long noreview = data.getLong("noreview");
      Long already = data.getLong("already");
      Long presentNew = data.getLong("present_new");
      Long presentRun = data.getLong("present_run");
      map.put("present", present);
      map.put("present_new", presentNew);
      map.put("present_run", presentRun);
      map.put("noreview", noreview);
      map.put("already", already);
    }

    return map;
  }

  /**
   * 查询三个司机端列表的订单数量.
   */
  
  public Map<String, Object> queryCounts(Long employId, Double longitude, Double latitude,
      Double distance, String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();

    Map<String, String> kv = new HashMap<String, String>();

    kv.put("employId", String.valueOf(employId));
    kv.put("longitude", String.valueOf(longitude));
    kv.put("latitude", String.valueOf(latitude));
    kv.put("distance", String.valueOf(distance));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(QUERY_COUNTS), String.class, kv);
    JSONObject jo = JSON.parseObject(result);
    int code = jo.getIntValue("code");
    if (code == 0) {
      JSONObject data = jo.getJSONObject("data");
      Long nearOrder = data.getLong("nearOrder");
      Long newOrder = data.getLong("newOrder");
      Long myWork = data.getLong("myWork");
      map.put("newOrder", newOrder);
      map.put("nearOrder", nearOrder);
      map.put("myWork", myWork);
    }

    return map;
  }
  
  /**
   * 接单.
   */
  
  public void updateToJiedan(
      Long orderId, Long employId, String employName, String employPhone,
      Long employCompanyId, String operator, Integer errandGrabAmount, String appKey) {
    String url = buildApi(UPDATE_STATUS_JIEDAN);
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    kv.put("orderId", String.valueOf(orderId));
    kv.put("action", "jiedan");
    kv.put("employId", String.valueOf(employId));
    kv.put("employName", employName);
    kv.put("employPhone", employPhone);
    kv.put("employCompanyId", String.valueOf(employCompanyId));
    if (errandGrabAmount != null) {
      kv.put("errandGrabAmount", String.valueOf(errandGrabAmount));
      url += "&errandGrabAmount={errandGrabAmount}";
    }
    kv.put("operator", operator);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);
    restTemplate.put(url, null, kv);
  }
  
  /**
   * 销单.
   */
  
  public void updateToCancel(Long orderId, String cause, String operator, String appKey) {

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    kv.put("orderId", String.valueOf(orderId));
    kv.put("action", "cancel");
    kv.put("cause", cause);
    kv.put("operator", operator);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    restTemplate.put(buildApi(UPDATE_STATUS_CANCEL), null, kv);
  }
  
  /**
   * 拒单.
   */
  
  public void updateToRefuse(Long orderId, Long employId, String cause, String operator,
      String appKey) {

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    kv.put("orderId", String.valueOf(orderId));
    kv.put("employId", String.valueOf(employId));
    kv.put("action", "refuse");
    kv.put("cause", cause);
    kv.put("operator", operator);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    restTemplate.put(buildApi(UPDATE_STATUS_REFUSE), null, kv);
  }
  
  /**
   * 跑腿订单出发.
   */
  
  public void updateToRun(Long orderId, String operator, String appKey) {

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    kv.put("orderId", String.valueOf(orderId));
    kv.put("action", "run");
    kv.put("operator", operator);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    restTemplate.put(buildApi(UPDATE_STATUS_RUN), null, kv);
  }

  public void updatePaidan(Long orderId, Long employId, String employName, String employPhone, Long employCompanyId,
                            String operator, String appKey){
    String message =null;
    StringBuilder sb = new StringBuilder();
    Map<String, String> kv = new HashMap<String, String>();
    sb.append(buildApi("api/orders/update.json")+ "?appKey={appKey}");
    sb.append("&action={action}");
    sb.append("&orderId={orderId}");
    sb.append("&employId={employId}");
    sb.append("&employName={employName}");
    sb.append("&employPhone={employPhone}");
    sb.append("&employCompanyId={employCompanyId}");
    sb.append("&operator={operator}");

    kv.put("action", String.valueOf("paidan"));
    kv.put("orderId", String.valueOf(orderId));
    kv.put("employId", String.valueOf(employId));
    kv.put("employName", String.valueOf(employName));
    kv.put("employPhone", String.valueOf(employPhone));
    kv.put("employCompanyId", String.valueOf(employCompanyId));
    kv.put("operator", String.valueOf(operator));
    kv.put("appKey", String.valueOf(appKey));
    restTemplate.put(sb.toString(), null, kv);
  }


  /**
   * 完成订单.
   */
  
  public void updateToFinish(Long orderId, String operator, String appKey) {

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    kv.put("orderId", String.valueOf(orderId));
    kv.put("action", "finish");
    kv.put("operator", operator);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    restTemplate.put(buildApi(UPDATE_STATUS_FINISH), null, kv);
  }
  
  /**
   * 评价订单.
   */
  
  public JSONObject review(Long orderId, double score, @RequestParam(value = "content", required = false)String content, String appKey) {
    Map<String, String> kv = new HashMap<>();
    kv.put("orderId", String.valueOf(orderId));
    kv.put("score", String.valueOf(score));
    kv.put("content", content);
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    ResponseEntity<String> responseEntity =
        restTemplate.postForEntity(buildApi(ORDER_REVIEW), null, String.class, kv);

    if (responseEntity.getStatusCode().is2xxSuccessful()) {
      return (JSONObject) JSON.parse(responseEntity.getBody());
    }

    return null;
  }
  
  /**
   * 根据城市查询收费信息.
   */
  
  public String findPriceInfo(String city, String acKey, String appKey) {

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("city", city);
    kv.put("acKey", acKey);
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(PRICE_INFO), String.class, kv);

    JSONObject jo = JSON.parseObject(result);
    if (jo.getIntValue("code") == 0) {
      JSONObject data = jo.getJSONObject("data");
      return data.getString("content");
    }

    return null;
  }

  private String buildApi(String api) {

    StringBuilder builder = new StringBuilder();
    builder.append(errandApiGateway);
    if (!errandApiGateway.endsWith("/")) {
      builder.append("/");
    }
    builder.append(api);

    return builder.toString();
  }

  private String buildApiDaijia(String server, String api) {

    StringBuilder builder = new StringBuilder();

    String daijiaServer = StringUtils.trimToEmpty(server).toLowerCase();
    if (!daijiaServer.startsWith("http://")&&!daijiaServer.startsWith("https://")) {
      builder.append("http://");
    } 
    builder.append(daijiaServer);
    if (!daijiaServer.endsWith("/")) {
      builder.append("/");
    }

    if (StringUtils.isNotBlank(api)) {
      builder.append(api);
    }

    return builder.toString();
  }
  
  /**
   * 查询车型.
   */
  
  public List<OrderType> findByCompanyId(Long companyId, String appKey) {
    List<OrderType> list = new ArrayList<OrderType>();

    Map<String, String> kv = new HashMap<String, String>();
    StringBuilder sb=new StringBuilder();
    sb.append("v2/orderType.json?appId={appId}&sign={sign}&appKey={appKey}");
    if(companyId!=null){
      kv.put("companyId", String.valueOf(companyId));
      sb.append("&companyId={companyId}");
    }
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);
    String result = restTemplate.getForObject(buildApi(String.valueOf(sb)), String.class, kv);
    
    JSONObject object = JSON.parseObject(result);

    int code = object.getIntValue("code");
    if (code == 0) {
      JSONArray jsonArray = object.getJSONArray("data");
      list = JSON.parseArray(jsonArray.toString(), OrderType.class);
    }
    return list;
  }
  
  /**
   * 查询一个类型.
   */
  
  public OrderType findOrderType(Long orderTypeId, String appKey) {
    OrderType orderType = null;
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderTypeId", String.valueOf(orderTypeId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(QUERY_ONE_TYPE), String.class, kv);

    JSONObject object = JSON.parseObject(result);

    int code = object.getIntValue("code");
    if (code == 0) {
      JSONObject data = object.getJSONObject("data");
      orderType = JSON.parseObject(data.toString(), OrderType.class);
    }
    return orderType;
  }
  
  /**
   * 查询单个类型.
   */
  
  public ResultTransport findOrderTypeV4(Long orderTypeId, String appKey) {
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderTypeId", String.valueOf(orderTypeId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(QUERY_ONE_TYPE_V4), String.class, kv);
    ResultTransport transport = JSON.parseObject(result, ResultTransport.class);

    return transport;
  }

  /**
   * v2创建跑腿订单.
   */
  public Order saveOrder(Order order) {
    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
    kv.add("passengerId", String.valueOf(order.getPassengerId()));
    kv.add("passengerName", order.getPassengerName());
    kv.add("passengerPhone", order.getPassengerPhone());
    kv.add("companyId", String.valueOf(order.getCompanyId()));
    kv.add("companyName", order.getCompanyName());
    kv.add("channelName", order.getChannelName());
    if (StringUtils.isNotBlank(order.getStartAddress())) {
      kv.add("startAddress", order.getStartAddress());
    }
    if (null != order.getStartLat()) {
      kv.add("startLat", String.valueOf(order.getStartLat()));
    }
    if (null != order.getStartLng()) {
      kv.add("startLng", String.valueOf(order.getStartLng()));
    }
    if (null != order.getStartTime()) {
      kv.add("startTime", String.valueOf(order.getStartTime().getTime()));
    }
    if (order.getStartPrice() != null) {
      kv.add("startPrice", String.valueOf(order.getStartPrice()));
    }
    if (order.getMileagePrice() != null) {
      kv.add("mileagePrice", String.valueOf(order.getMileagePrice()));
    }
    if (order.getTravelTimePrice() != null) {
      kv.add("travelTimePrice", String.valueOf(order.getTravelTimePrice()));
    }
    if (order.getMileage() != null) {
      kv.add("mileage", String.valueOf(order.getMileage()));
    }
    if (order.getTravelTime() != null) {
      kv.add("travelTime", String.valueOf(order.getTravelTime()));
    }
    if (order.getShouldPay() != null) {
      kv.add("shouldPay", order.getShouldPay() != null ? String.valueOf(order.getShouldPay())
          : null);
    }
    if (order.getRealPay() != null) {
        kv.add("realPay", order.getRealPay() != null ? String.valueOf(order.getRealPay())
            : null);
      }
    kv.add("orderTypeId", String.valueOf(order.getOrderTypeId()));
    if (StringUtils.isNotBlank(order.getContent())) {
      kv.add("content", order.getContent());
    }
    if (StringUtils.isNotBlank(order.getDeliverAddress()) && order.getDeliverLat() != null
        && order.getDeliverLng() != null) {
      kv.add("deliverAddress", order.getDeliverAddress());
      kv.add("deliverLat", String.valueOf(order.getDeliverLat()));
      kv.add("deliverLng", String.valueOf(order.getDeliverLng()));
    }
    if (order.getCouponId() != null) {
      kv.add("couponId", String.valueOf(order.getCouponId()));
    }
    if (order.getCouponMoney() != null) {
      kv.add("couponMoney", String.valueOf(order.getCouponMoney()));
    }
    if (order.getEmployId() != null) {
      kv.add("employId", String.valueOf(order.getEmployId()));
    }
    if (order.getEmployName() != null) {
      kv.add("employName", order.getEmployName());
    }
    if (order.getEmployPhone() != null) {
      kv.add("employPhone", order.getEmployPhone());
    }
    if (order.getEmployCompanyId() != null) {
      kv.add("employCompanyId", String.valueOf(order.getEmployCompanyId()));
    }
    if (order.getStartDetailed() != null) {
        kv.add("startDetailed", String.valueOf(order.getStartDetailed()));
    }
    if (order.getEndDetailed() != null) {
        kv.add("endDetailed", String.valueOf(order.getEndDetailed()));
    }
    if (order.getRecipients() != null) {
        kv.add("recipients", String.valueOf(order.getRecipients()));
    }
    if (order.getPhone() != null) {
        kv.add("phone", String.valueOf(order.getPhone()));
    }
    if (order.getWeight() != null) {
        kv.add("weight", String.valueOf(order.getWeight()));
    }
    if (order.getMatter() != null) {
        kv.add("matter", String.valueOf(order.getMatter()));
    }
    if (order.getBuyNeeds() != null) {
        kv.add("buyNeeds", String.valueOf(order.getBuyNeeds()));
    }
    if (order.getGoodsCash() != null) {
        kv.add("goodsCash", String.valueOf(order.getGoodsCash()));
    }
    if (order.getThanksCash() != null) {
        kv.add("thanksCash", String.valueOf(order.getThanksCash()));
    }
    if (order.getTips() != null) {
        kv.add("tips", String.valueOf(order.getTips()));
    }
    if (order.getAddServices() != null) {
        kv.add("addServices", String.valueOf(order.getAddServices()));
    }
    if (order.getPrePayTypeDetail()!=null){
        kv.add("prePayTypeDetail", String.valueOf(order.getPrePayTypeDetail()));
    }
    
    kv.add("appKey", order.getAppkey());
    String result = postMultiValueMap(buildApi(SAVE_ORDER), kv);
    JSONObject parseObject = JSON.parseObject(result);
    if (parseObject.getIntValue("code") == 0) {
      JSONObject jo = parseObject.getJSONObject("data");
      order = JSON.parseObject(jo.toString(), Order.class);
      return order;
    } else {
      return null;
    }

  }
  
  /**
   * 补单V4.
   */
  
  public ResultTransport saveOrderV4(Order order) {
    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
    kv.add("passengerId", String.valueOf(order.getPassengerId()));
    kv.add("passengerName", order.getPassengerName());
    kv.add("passengerPhone", order.getPassengerPhone());
    kv.add("companyId", String.valueOf(order.getCompanyId()));
    kv.add("companyName", order.getCompanyName());
    kv.add("channelName", order.getChannelName());
    kv.add("startAddress", order.getStartAddress());
    kv.add("startLat", String.valueOf(order.getStartLat()));
    kv.add("startLng", String.valueOf(order.getStartLng()));
    if (order.getStartPrice() != null) {
      kv.add("startPrice", String.valueOf(order.getStartPrice()));
    }
    if (order.getMileagePrice() != null) {
      kv.add("mileagePrice", String.valueOf(order.getMileagePrice()));
    }
    if (order.getTravelTimePrice() != null) {
      kv.add("travelTimePrice", String.valueOf(order.getTravelTimePrice()));
    }
    if (order.getMileage() != null) {
      kv.add("mileage", String.valueOf(order.getMileage()));
    }
    if (order.getTravelTime() != null) {
      kv.add("travelTime", String.valueOf(order.getTravelTime()));
    }
    if (order.getShouldPay() != null) {
      kv.add("shouldPay", order.getShouldPay() != null ? String.valueOf(order.getShouldPay())
          : null);
    }
    kv.add("orderTypeId", String.valueOf(order.getOrderTypeId()));
    kv.add("content", order.getContent());
    if (StringUtils.isNotBlank(order.getDeliverAddress()) && order.getDeliverLat() != null
        && order.getDeliverLng() != null) {
      kv.add("deliverAddress", order.getDeliverAddress());
      kv.add("deliverLat", String.valueOf(order.getDeliverLat()));
      kv.add("deliverLng", String.valueOf(order.getDeliverLng()));
    }
    if (order.getCouponId() != null) {
      kv.add("couponId", String.valueOf(order.getCouponId()));
    }
    if (order.getCouponMoney() != null) {
      kv.add("couponMoney", String.valueOf(order.getCouponMoney()));
    }
    if (order.getEmployId() != null) {
      kv.add("employId", String.valueOf(order.getEmployId()));
    }
    if (order.getEmployName() != null) {
      kv.add("employName", order.getEmployName());
    }
    if (order.getEmployPhone() != null) {
      kv.add("employPhone", order.getEmployPhone());
    }
    if (order.getEmployCompanyId() != null) {
      kv.add("employCompanyId", String.valueOf(order.getEmployCompanyId()));
    }
    if (order.getWeight() != null) {
        kv.add("weight", String.valueOf(order.getWeight()));
      }
    kv.add("appKey", order.getAppkey());
    String result = postMultiValueMap(buildApi(SAVE_ORDER_V4), kv);

    ResultTransport transport = JSON.parseObject(result, ResultTransport.class);

    return transport;
  }
  
  /**
   * 查询单个订单V2.
   */
  
  public Map<String, Object> findOrderV2(Long orderId, String appKey, String address) {
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderId", String.valueOf(orderId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(FIND_ONE_ORDER), String.class, kv);

    JSONObject jo = JSON.parseObject(result);
    Map<String, Object> map = new HashMap<String, Object>();
    if (jo.getIntValue("code") == 0) {
      Order order = jo.getObject("data", Order.class);

      map.put("orderId", order.getId());
      map.put("orderNo", order.getOrderNo());
      map.put("content", order.getContent());
      map.put("startTime", order.getStartTime() != null ? order.getStartTime().getTime() : new Date().getTime());
      map.put("serverTime", order.getStartTime() != null ? order.getStartTime().getTime() : new Date().getTime());
      Calendar ca=Calendar.getInstance();
  	  ca.setTime(order.getCreated());
  	  ca.add(Calendar.HOUR_OF_DAY, 2);
      if(order.getStartTime().getTime() - ca.getTime().getTime() > 0){
  	    //预约时间大于创建时间2小时订单状态为预约订单
    	  map.put("ifNow", false);
      }else{
    	  map.put("ifNow", true);
      }
      map.put("endAddress", order.getDeliverAddress()!=null?order.getDeliverAddress():"");
      map.put("endLat", order.getDeliverLat());
      map.put("endLng", order.getDeliverLng());
      map.put("status", order.getStatus());
      map.put("shouldPay", order.getShouldPay());
      map.put("passengerId", order.getPassengerId());
      map.put("passengerName", order.getPassengerName());
      map.put("passengerPhone", StringUtils.isNotBlank(order.getAnonymousNumber())?order.getAnonymousNumber():order.getPassengerPhone());
      map.put("companyId", order.getCompanyId());
      map.put("companyName", order.getCompanyName());
      map.put("review", order.getReview());
      map.put("employName", order.getEmployName());
      map.put("employPhone", order.getEmployPhone());
      map.put("lasturge", order.getLasturge().getTime());
      map.put("tips", order.getTips());
      map.put("addService", order.getAddServices());
      map.put("orderTypeId", order.getOrderTypeId());
      map.put("orderTypeOtherServices", order.getOtherServices());
      map.put("tipsList", order.getTipsList());
      map.put("errandOrderTypeDetaileds", order.getErrandOrderTypeDetaileds());
      map.put("weight", order.getWeight());
      map.put("startDetailed", order.getStartDetailed());
      map.put("endDetailed", order.getEndDetailed());
      map.put("buyNeeds", order.getBuyNeeds()!=null?order.getBuyNeeds():"");
      map.put("content", order.getContent()!=null?order.getContent():"");
      map.put("tips", order.getTips());
      map.put("addServices", order.getAddServices());
      map.put("goodsCash", order.getGoodsCash());
      map.put("thanksCash", order.getThanksCash());
      map.put("recipients", order.getRecipients()!=null?order.getRecipients():"");
      map.put("phone", order.getPhone()!=null?order.getPhone():"");
      Long employId = order.getEmployId();
      if (employId != null && employId != 0) {
        StringBuilder builder = new StringBuilder();
        builder.append(buildApiDaijia(address, "api/daijia/queryDriver.json?driverId={driverId}"));
        String employResult = restTemplate.getForObject(builder.toString(), String.class, employId);
        JSONObject jsonObject = JSON.parseObject(employResult);
        Boolean success = jsonObject.getBoolean("success");
        if (success) {
          String employPhoto = jsonObject.getString("employPhoto");
          String errandserviceType = jsonObject.getString("errandserviceType");
          String platNo = jsonObject.getString("platNo");
          Double employScore = jsonObject.getDouble("employScore");
          map.put("employId", employId);
          map.put("employName", order.getEmployName());
          map.put("employPhone", StringUtils.isNotBlank(order.getAnonymousNumber())?order.getAnonymousNumber():order.getEmployPhone());
          map.put("employScore", employScore);
          map.put("employPhoto", employPhoto);
          map.put("errandserviceType", errandserviceType);
          map.put("platNo", platNo);
        }
      } else {
        map.remove("employId");
      }
      if (order.getStatus() == 2 && order.getAreaId() != null) {
        Area area = new Area();
        StringBuilder builder2 = new StringBuilder();
        builder2.append(buildApiDaijia(address, "api/daijia/queryArea.json?areaId={areaId}"));
        String result2 =
            restTemplate.getForObject(builder2.toString(), String.class, order.getAreaId());
        JSONObject jsonObject = JSON.parseObject(result2);
        Boolean success = jsonObject.getBoolean("success");
        if (success) {
          JSONObject data = jsonObject.getJSONObject("data");
          area = JSON.parseObject(data.toString(), Area.class);
        }
        map.put("area", area);
      }
      // 订单的评分和评价内容
      OrderReview orderReview = order.getOrderReview();
      if (orderReview != null) {
        map.put("orderScore", orderReview.getScore());
        map.put("orderContent", orderReview.getContent());
      }
      map.put("channelName", order.getChannelName());
      map.put("orderType", order.getOrderType());
      map.put("imgs", order.getImgs());// 多张图片地址
      map.put("startAddress", order.getStartAddress());
      map.put("startLat", order.getStartLat());
      map.put("startLng", order.getStartLng());
      map.put("realPay", order.getRealPay());
      map.put("treatment", order.isTreatment());
    }
    return map;
  }

  /**
   * 查询单个订单V4.
   */
  public ResultTransport findOrderV4(Long orderId, String appKey, String address) {
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderId", String.valueOf(orderId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(FIND_ONE_ORDER_V4), String.class, kv);

    ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

    if (resultTransport.getCode() == 0) {
      Map<String, Object> map = (Map<String, Object>) resultTransport.getData();
      Object object2 = map.get("areaId");
      map.remove("areaId");
      Long areaId = Long.valueOf(object2.toString());
      if (areaId != null) {
        StringBuilder builder2 = new StringBuilder();
        builder2.append(buildApiDaijia(address,
            "api/company/v4/findChargeStartTimes.json?areaId={areaId}"));
        String result2 = restTemplate.getForObject(builder2.toString(), String.class, areaId);
        ResultTransport areaTransport = JSON.parseObject(result2, ResultTransport.class);
        if (areaTransport.getCode() == 0) {
          List<ChargeStartTime> chargeStartTimes =
              JSON.parseArray(areaTransport.getData().toString(), ChargeStartTime.class);
          map.put("chargeStartTimes", chargeStartTimes);
        }
      }
      resultTransport.setData(map);
    }
    return resultTransport;
  }
  
  /**
   * 查询单个订单V2.
   */
  
  public Order findOneOrderV2(Long orderId, String appKey) {
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderId", String.valueOf(orderId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(FIND_ONE_ORDER), String.class, kv);

    JSONObject jo = JSON.parseObject(result);
    Order order = null;
    if (jo.getIntValue("code") == 0) {
      order = jo.getObject("data", Order.class);
    }
    return order;
  }

  /**
   * 客户端 根据状态查询订单.
   */
  
  public DataGrid<Map<String, Object>> findByStatusV2(Long passengerId, Integer page, Integer rows,
      String appKey, String address) throws Exception {
    DataGrid<Map<String, Object>> dataGrid = new DataGrid<Map<String, Object>>();
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("passengerId", String.valueOf(passengerId));
    kv.put("status", "uncancel");
    kv.put("orderby", "status asc,review asc,created desc");
    kv.put("page", String.valueOf(page));
    kv.put("rows", String.valueOf(rows));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);
    String result = restTemplate.getForObject(buildApi(FIND_BY_STATUS_V2), String.class, kv);
    JSONObject object = JSON.parseObject(result);
    int code = object.getIntValue("code");
    List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
    if (code == 0) {

      JSONObject json = object.getJSONObject("data");
      long total = json.getLong("total");

      dataGrid.setTotal(total);
      List<Order> list = new ArrayList<Order>();

      JSONArray jsonArray = json.getJSONArray("rows");
      list = JSON.parseArray(jsonArray.toString(), Order.class);
      for (Order order : list) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orderId", order.getId());
        map.put("orderNo", order.getOrderNo());
        map.put("content", order.getContent());
        map.put("serverTime", order.getStartTime() != null ? order.getStartTime().getTime() : new Date().getTime());
        map.put("startTime", order.getStartTime() != null ? order.getStartTime().getTime() : new Date().getTime());
        if(null != order.getStartTime()){
	        Calendar ca=Calendar.getInstance();
	    	  ca.setTime(order.getCreated());
	    	  ca.add(Calendar.HOUR_OF_DAY, 2);
	        if(order.getStartTime().getTime() - ca.getTime().getTime() > 0){
	    	    //预约时间大于创建时间2小时订单状态为预约订单
	      	  map.put("ifNow", false);
	        }else{
	      	  map.put("ifNow", true);
	        }
        }else{
        	map.put("ifNow", true);
        }
        map.put("endAddress", order.getDeliverAddress());
        map.put("endLat", order.getDeliverLat());
        map.put("endLng", order.getDeliverLng());
        map.put("status", order.getStatus());
        map.put("shouldPay", order.getShouldPay());
        map.put("passengerId", order.getPassengerId());
        map.put("passengerName", order.getPassengerName());
        map.put("passengerPhone", StringUtils.isNotBlank(order.getAnonymousNumber())?order.getAnonymousNumber():order.getPassengerPhone());
        map.put("companyId", order.getCompanyId());
        map.put("companyName", order.getCompanyName());
        map.put("review", order.getReview());
        map.put("lasturge", order.getLasturge().getTime());
        map.put("tips", order.getTips());
        map.put("addService", order.getAddServices());
        map.put("orderTypeId", order.getOrderTypeId());
        map.put("orderTypeOtherServices", order.getOtherServices());
        map.put("tipsList", order.getTipsList());
        map.put("errandOrderTypeDetaileds", order.getErrandOrderTypeDetaileds());
        map.put("weight", order.getWeight());
        map.put("startDetailed", order.getStartDetailed());
        map.put("endDetailed", order.getEndDetailed());
        map.put("buyNeeds", order.getBuyNeeds()!=null?order.getBuyNeeds():"");
        map.put("content", order.getContent()!=null?order.getContent():"");
        map.put("tips", order.getTips());
        map.put("addServices", order.getAddServices());
        map.put("goodsCash", order.getGoodsCash());
        map.put("thanksCash", order.getThanksCash());
        map.put("recipients", order.getRecipients()!=null?order.getRecipients():"");
        map.put("phone", order.getPhone()!=null?order.getPhone():"");
        Long employId = order.getEmployId();
        if (employId != null && employId != 0) {
          StringBuilder builder = new StringBuilder();
          builder
              .append(buildApiDaijia(address, "api/daijia/queryDriver.json?driverId={driverId}"));
          String employResult =
              restTemplate.getForObject(builder.toString(), String.class, employId);
          JSONObject jsonObject = JSON.parseObject(employResult);
          Boolean success = jsonObject.getBoolean("success");
          if (success) {
            String employPhoto = jsonObject.getString("employPhoto");
            String errandserviceType = jsonObject.getString("errandserviceType");
            String platNo = jsonObject.getString("platNo");
            Double employScore = jsonObject.getDouble("employScore");
            map.put("employId", employId);
            map.put("employName", order.getEmployName());
            map.put("employPhone", StringUtils.isNotBlank(order.getAnonymousNumber())?order.getAnonymousNumber():order.getEmployPhone());
            map.put("employScore", employScore);
            map.put("employPhoto", employPhoto);
            map.put("errandserviceType", errandserviceType);
            map.put("platNo", platNo);
          }
        }

        // 订单的评分和评价内容
        OrderReview orderReview = order.getOrderReview();
        if (orderReview != null) {
          map.put("orderScore", orderReview.getScore());
          map.put("orderContent", orderReview.getContent());
        }
        map.put("channelName", order.getChannelName());
        map.put("orderType", order.getOrderType());
        map.put("imgs", order.getImgs());// 多张图片地址
        map.put("startAddress", order.getStartAddress());
        map.put("startLat", order.getStartLat());
        map.put("startLng", order.getStartLng());
        
        // 处理空指针
        Double startPrice = order.getStartPrice() == null ? 0 : order.getStartPrice();
        Double travelTimePrice = order.getTravelTimePrice() == null ? 0 : order.getTravelTimePrice();
        Double mileagePrice = order.getMileagePrice() == null ? 0 : order.getMileagePrice();

        map.put("realPay", startPrice  + travelTimePrice + mileagePrice);
        map.put("treatment", order.isTreatment());
        listMap.add(map);
      }
    }
    dataGrid.setRows(listMap);

    return dataGrid;
  }

  /**
   * v2评价订单.
   */
  
  public JSONObject reviewV2(Long orderId, double score, String content, String appKey) {
    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
    kv.add("orderId", String.valueOf(orderId));
    kv.add("score", String.valueOf(score));
    kv.add("content", content);
    kv.add("appKey", appKey);
    String result = postMultiValueMap(buildApi(ORDER_REVIEW_V2), kv);
    return JSON.parseObject(result);
  }

  /**
   * V5获取跑腿订单评价
   * @param orderId 订单Id
   * @param appKey 系统Key
   * @return
   */
  public JSONObject getReviewV5 (Long orderId, String appKey) {
	  Map<String, String> params = new HashMap<String, String>();
	  params.put("orderId", String.valueOf(orderId));
	  params.put("appKey", appKey);

	  String sign = SignHelper.sign(SignHelper.buildSignMessage(params), errandAppKey);
	  params.put("sign", sign);
	  params.put("appId", errandAppId);
	  String rs = restTemplate.getForObject(buildApi(EMPLOY_SCORE), String.class, params);
	  return JSONObject.parseObject(rs);
  }
  
  /**
   * 封装多部件请求.
   */
  
  public String postMultiValueMap(String url, MultiValueMap<String, String> kv) {

    Set<Entry<String, List<String>>> entries = kv.entrySet();

    Map<String, String> params = new HashMap<String, String>();
    for (Entry<String, List<String>> entry : entries) {
      List<String> values = entry.getValue();
      params.put(entry.getKey(), CollectionUtils.isEmpty(values) ? null : values.get(0));
    }

    String sign = SignHelper.sign(SignHelper.buildSignMessage(params), errandAppKey);

    kv.add("sign", sign);
    kv.add("appId", errandAppId);
    return restTemplate.postForObject(url, kv, String.class);

  }
  
  /**
   * 催单.
   */
  
  public String hastenV2(Long orderId, String appKey) {
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("orderId", String.valueOf(orderId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);
    String result = restTemplate.getForObject(buildApi(HASTEN_ORDER_V2), String.class, kv);
    JSONObject jo = JSON.parseObject(result);

    if (jo.getIntValue("code") == 0) {
      return "success";
    } else {
      return "fail";
    }
  }
  
  /**
   * 跑腿销单V2.
   */
  
  public void updateToCancenV2(Long orderId, String cause, String operator, String appKey) {

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    kv.put("orderId", String.valueOf(orderId));
    kv.put("action", "cancel");
    kv.put("cause", cause);
    kv.put("operator", operator);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    restTemplate.put(buildApi(UPDATE_STATUS_CANCEL_V2), null, kv);
  }
  
  /**
   * 跑腿接单V2.
   */
  
  public void updateToJiedanV2(Long orderId, Long employId, String employName, String employPhone,
      Long employCompanyId, String operator, String appKey) {
    String url = buildApi(UPDATE_STATUS_JIEDAN_V2);
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    kv.put("orderId", String.valueOf(orderId));
    kv.put("employId", String.valueOf(employId));
    kv.put("employName", employName);
    kv.put("employPhone", employPhone);
    kv.put("operator", operator);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);
    try {
      restTemplate.put(url, null, kv);
    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
  }

  /**
   * V2抢单.
   */
  
  public void grabOrder(Long orderId, Long employId, String employName, String employPhone,
      Long employCompanyId, String operator, String appKey) {
    String url = buildApi(GRAB_ORDER_V2);
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    kv.put("orderId", String.valueOf(orderId));
    kv.put("employId", String.valueOf(employId));
    kv.put("employName", employName);
    kv.put("employPhone", employPhone);
    kv.put("operator", operator);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);
    try {
      restTemplate.put(url, null, kv);
    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
  }

  /**
   * V2司机当前任务(已接单,已执行但未完成的).
   */
  
  public DataGrid<Map<String, Object>> findMyWorkV2(Long employId, Double longitude,
      Double latitude, Integer page, Integer rows, String appKey, String address) {
    DataGrid<Map<String, Object>> dataGrid = new DataGrid<Map<String, Object>>();

    List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();

    Map<String, String> kv = new HashMap<String, String>();
    String url = buildApi(FIND_MY_WORK_V2);
    kv.put("employId", String.valueOf(employId));
    kv.put("page", String.valueOf(page));
    kv.put("rows", String.valueOf(rows));
    kv.put("orderby", "status asc,deliverTime desc");
    kv.put("status", "myWork");
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    if (longitude != null && longitude != 0) {
      kv.put("longitude", String.valueOf(longitude));
      url += "&longitude={longitude}";
    }
    if (latitude != null && latitude != 0) {
      kv.put("latitude", String.valueOf(latitude));
      url += "&latitude={latitude}";
    }
    if (longitude != null && latitude != null) {
      kv.put("distance", String.valueOf(10000));
      url += "&distance={distance}";
    }
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);
    String result = restTemplate.getForObject(url, String.class, kv);
    JSONObject object = JSON.parseObject(result);

    int code = object.getIntValue("code");
    if (code == 0) {
      JSONObject json = object.getJSONObject("data");
      long total = json.getLong("total");
      dataGrid.setTotal(total);

      List<Order> list = new ArrayList<Order>();
      JSONArray jsonArray = json.getJSONArray("rows");
      list = JSON.parseArray(jsonArray.toString(), Order.class);

      for (int i = 0; i < list.size(); i++) {
        Order order = list.get(i);
        Double length =
            Distance.doubleVal(order.getStartLat(), order.getStartLng(), latitude, longitude);
        if (length > 0 && length <= 1) {
          BigDecimal decimal = new BigDecimal(1000 * length);
          BigDecimal abs = decimal.abs(new MathContext(3));
          String str = abs.intValue() + "米";
          order.setDistanceStr(str);
          order.setDistance(new BigDecimal(length).abs(new MathContext(3)).doubleValue());
        } else if (length > 1) {
          BigDecimal decimal = new BigDecimal(length);
          if (length <= 10) {
            BigDecimal abs = decimal.abs(new MathContext(2));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(2)).doubleValue());
          } else if (length > 10 && length < 100) {
            BigDecimal abs = decimal.abs(new MathContext(3));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(3)).doubleValue());
          } else if (length > 100 && length <= 1000) {
            BigDecimal abs = decimal.abs(new MathContext(4));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(4)).doubleValue());
          } else {
            BigDecimal abs = decimal.abs(new MathContext(5));
            String str = abs + "公里";
            order.setDistanceStr(str);
            order.setDistance(new BigDecimal(length).abs(new MathContext(5)).doubleValue());
          }

        }
      }
      // 排序(根据该司机的位置和订单的交付地址的距离由近到远排序).....
      for (int i = 0; i < list.size(); i++) {
        Order order = list.get(i);
        Double dis = order.getDistance();
        for (int j = 0; j < list.size(); j++) {
          Order ord = list.get(j);
          Double d2 = ord.getDistance();
          if (dis < d2) {
            Order temp = list.get(i);
            list.set(i, ord);
            list.set(j, temp);
          }
        }
      }
      // 排序.....结束....

      for (Order order : list) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orderId", order.getId());
        map.put("orderNo", order.getOrderNo());
        map.put("content", order.getContent());
        map.put("deliverAddress", order.getDeliverAddress());
        map.put("deliverLat", order.getDeliverLat());
        map.put("deliverLng", order.getDeliverLng());
        map.put("status", order.getStatus());
        map.put("passengerId", order.getPassengerId());
        map.put("passengerName", order.getPassengerName());
        map.put("passengerPhone", order.getPassengerPhone());
        map.put("companyId", order.getCompanyId());
        map.put("companyName", order.getCompanyName());
        map.put("shouldPay", order.getShouldPay());
        map.put("employName", order.getEmployName());
        map.put("employPhone", order.getEmployPhone());
        StringBuilder builder = new StringBuilder();
        builder.append("\n");
        for (OrderMemo o : order.getMemoList()) {
          builder.append(o.getMemo() + "\n");
        }
        map.put("memoStr", builder.toString());

        map.put("channelName", order.getChannelName());
        map.put("orderType", order.getOrderType());
        map.put("imgs", order.getImgs());// 多张图片地址
        map.put("startAddress", order.getStartAddress());
        map.put("startTime", order.getStartTime() != null ? order.getStartTime().getTime() : null);
        map.put("startLat", order.getStartLat());
        map.put("startLng", order.getStartLng());
        map.put("distance", order.getDistance());
        map.put("distanceStr", order.getDistanceStr());
        map.put("mileage", order.getMileage());
        map.put("travelTime", order.getTravelTime());
        map.put("startPrice", order.getStartPrice());
        map.put("mileagePrice", order.getMileagePrice());
        map.put("travelTimePrice", order.getTravelTimePrice());
        Area area = new Area();
        if (order.getAreaId() != null) {
          StringBuilder builder2 = new StringBuilder();
          builder2.append(buildApiDaijia(address, "api/daijia/queryArea.json?areaId={areaId}"));
          String result2 =
              restTemplate.getForObject(builder2.toString(), String.class, order.getAreaId());
          JSONObject jsonObject = JSON.parseObject(result2);
          Boolean success = jsonObject.getBoolean("success");
          if (success) {
            JSONObject data = jsonObject.getJSONObject("data");
            area = JSON.parseObject(data.toString(), Area.class);
          }
        }
        map.put("area", area);
        listMap.add(map);
      }
    }
    dataGrid.setRows(listMap);

    return dataGrid;
  }

  /**
   * 查询服务人员已经执行完的订单.
   */
  
  public DataGrid<Map<String, Object>> queryFinishOrderV2(Long employId, Integer page,
      Integer rows, String appKey) {
    DataGrid<Map<String, Object>> dataGrid = new DataGrid<Map<String, Object>>();

    List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();

    Map<String, String> kv = new HashMap<String, String>();
    String url = buildApi(FIND_FINISH_ORDER_V2);
    kv.put("employId", String.valueOf(employId));
    kv.put("page", String.valueOf(page));
    kv.put("rows", String.valueOf(rows));
    kv.put("orderby", "created asc");
    kv.put("status", "finish");
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);
    String result = restTemplate.getForObject(url, String.class, kv);
    JSONObject object = JSON.parseObject(result);

    int code = object.getIntValue("code");
    if (code == 0) {
      JSONObject json = object.getJSONObject("data");
      long total = json.getLong("total");
      dataGrid.setTotal(total);

      List<Order> list = new ArrayList<Order>();
      JSONArray jsonArray = json.getJSONArray("rows");
      list = JSON.parseArray(jsonArray.toString(), Order.class);

      for (Order order : list) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("orderNo", order.getOrderNo());
        map.put("deliverAddress", order.getDeliverAddress());
        map.put("shouldPay", order.getRealPay());
        map.put("orderType", order.getOrderType());
        map.put("finishTime", order.getUpdated());
        map.put("startAddress", order.getStartAddress());
        listMap.add(map);
      }
    }
    dataGrid.setRows(listMap);

    return dataGrid;
  }
  
  /**
   * 查询跑腿类型.
   */
  
  public ResultTransport queryTypeV4(Long companyId, String detailedJobType, String appKey) {
    Map<String, String> kv = new HashMap<String, String>();
    String url = buildApi(QUERY_TYPE_V4);
    if (companyId != null && companyId != 0) {
      kv.put("companyId", String.valueOf(companyId));
      url += "&companyId={companyId}";
    }
    if (StringUtils.isNotBlank(detailedJobType)) {
      kv.put("detailedJobType", detailedJobType);
      url += "&detailedJobType={detailedJobType}";
    }

    kv.put("appKey", appKey);

    String result = restTemplate.getForObject(url, String.class, kv);

    ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

    return resultTransport;
  }

  /**
   * 查询跑腿类型V5
   * @param companyId 公司
   * @param appKey
   * @return
   */
  public ResultV5 queryTypeV5(Long companyId, String appKey) {
		Map<String, String> kv = new HashMap<String, String>();
		String url = buildApi(QUERY_TYPE_V5);
		if (companyId != null && companyId != 0) {
			kv.put("companyId", String.valueOf(companyId));
			url += "&companyId={companyId}";
		}

		kv.put("appKey", appKey);

		String result = restTemplate.getForObject(url, String.class, kv);

		ResultV5 resultTransport = JSON.parseObject(result, ResultV5.class);

		return resultTransport;
  }

  /**
   * 接单V4.
 * @param platNo 
 * @param errandserviceType 
   */
  
  public ResultTransport updateToJiedanV4(Long orderId, Long employId, String employName,
      String employPhone, Long companyId, String employAccount, String employPhoto,
      Double employScore, String operator, String appKey, String errandserviceType, String platNo) {

    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();

    kv.add("orderId", String.valueOf(orderId));
    kv.add("appKey", appKey);
    kv.add("orderId", String.valueOf(orderId));
    kv.add("employId", String.valueOf(employId));
    kv.add("employName", employName);
    kv.add("employPhone", employPhone);
    kv.add("employCompanyId", String.valueOf(companyId));
    kv.add("operator", operator);
    kv.add("employNo", employAccount);
    kv.add("employScore", String.valueOf(employScore));
    if (StringUtils.isNotBlank(employPhoto)) {
      kv.add("employPhoto", employPhoto);
    }
    if (StringUtils.isNotBlank(errandserviceType)) {
        kv.add("errandserviceType", errandserviceType);
    }
    if (StringUtils.isNotBlank(platNo)) {
        kv.add("platNo", platNo);
    }

    String result = postMultiValueMap(buildApi(UPDATE_JIEDAN_V4), kv);

    ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

    return resultTransport;
  }
  
  /**
   * 拒单V4.
   */
  
  public ResultTransport refuse(
      Long orderId, Long employId, String cause, String operator, String appKey) {
    
    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
    
    kv.add("appKey", appKey);
    kv.add("orderId", String.valueOf(orderId));
    kv.add("employId", String.valueOf(employId));
    kv.add("cause", cause);
    kv.add("operator", operator);

    String result = postMultiValueMap(buildApi(UPDATE_REFUSE_V4), kv);

    ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

    return resultTransport;
  }
  
  /**
   * 跑腿订单出发.
   */

  public ResultTransport runV4(Long orderId, String operator, String appKey) {
    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();

    kv.add("appKey", appKey);
    kv.add("orderId", String.valueOf(orderId));
    kv.add("operator", operator);

    String result = postMultiValueMap(buildApi(UPDATE_RUN_V4), kv);

    ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

    return resultTransport;
  }

  
  /**
   * 查询公司的车型.
   */
  
  public JSONArray queryTypes(Long companyId, String appKey) {
    Map<String, String> kv = new HashMap<String, String>();
    kv.put("companyId", String.valueOf(companyId));
    kv.put("appKey", appKey);
    kv.put("appId", errandAppId);
    String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);
    kv.put("sign", sign);

    String result = restTemplate.getForObject(buildApi(QUERY_TYPE_V4), String.class, kv);
    JSONObject object = JSON.parseObject(result);
    JSONArray jsonArray = null;
    if (object.getIntValue("code") == 0) {
      jsonArray = object.getJSONArray("data");
    }

    return jsonArray;

  }

  /**
   * V4抢单.
   */
  
  public ResultTransport grabV4(Long orderId, Long employId, String employName, String employPhone,
      Long companyId, String employAccount, String employPhoto, Double employScore,
      String operator, String appKey) {

    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();

    kv.add("orderId", String.valueOf(orderId));
    kv.add("appKey", appKey);
    kv.add("orderId", String.valueOf(orderId));
    kv.add("employId", String.valueOf(employId));
    kv.add("employName", employName);
    kv.add("employPhone", employPhone);
    kv.add("employCompanyId", String.valueOf(companyId));
    kv.add("operator", operator);
    kv.add("employNo", employAccount);
    kv.add("employScore", String.valueOf(employScore));
    if (StringUtils.isNotBlank(employPhoto)) {
      kv.add("employPhoto", employPhoto);
    }

    String result = postMultiValueMap(buildApi(UPDATE_JIEDAN_V4), kv);

    ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

    return resultTransport;
  }

  /**
   * 添加抢单记录.
 * @param platNo 
 * @param errandserviceType 
   */
  
  public ResultTransport toGrabOrderV4(Long orderId, Long employId, String employName,
      String employPhone, Long companyId, Double employLat, Double employLng, String appKey, String errandserviceType, String platNo) {
    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();

    kv.add("appKey", appKey);
    kv.add("orderId", String.valueOf(orderId));
    kv.add("employId", String.valueOf(employId));
    kv.add("employName", employName);
    kv.add("employPhone", employPhone);
    kv.add("employCompanyId", String.valueOf(companyId));
    kv.add("employLat", String.valueOf(employLat));
    kv.add("employLng", String.valueOf(employLng));
    kv.add("errandserviceType",errandserviceType);
    kv.add("platNo", platNo);

    String result = postMultiValueMap(buildApi(ADDGRAB_V4), kv);

    ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

    return resultTransport;
  }
  
  /**
   * 查询执行中的订单.
   */
  
  public JSONArray findRunning(Long passengerId, String appKey) {

    Map<String, String> kv = new HashMap<String, String>();
    kv.put("passengerId", String.valueOf(passengerId));
    kv.put("allstatus", "0,1,2,3");
    kv.put("appKey", appKey);

    String result = restTemplate.getForObject(buildApi(FIND_RUNNING), String.class, kv);
    JSONObject object = JSON.parseObject(result);
    int code = object.getInteger("code");
    JSONArray jsonArray = null;
    if (code == 0) {
      JSONObject json = object.getJSONObject("data");
      jsonArray = json.getJSONArray("rows");
    }
    return jsonArray;
  }

  /**
   * 指派订单.
   */
  
  public ResultTransport grabOrderV4(Long orderId, String appKey) {
    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();

    kv.add("appKey", appKey);
    kv.add("orderId", String.valueOf(orderId));

    String result = postMultiValueMap(buildApi(GRAB_ORDER_V4), kv);

    ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

    return resultTransport;
  }

  /**
   * V4销单(司机端).
   */
  
  public ResultTransport cancelV4(Long orderId, String cause, String appKey) {
    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();

    kv.add("orderId", String.valueOf(orderId));
    kv.add("cause", cause);
    kv.add("appKey", appKey);

    String result = postMultiValueMap(buildApi(CANCEL_V4), kv);

    ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

    return resultTransport;
  }
  
  /**
   * 修改终点地址.
   */
  
  public ResultTransport updateToPlace(Long orderId, String toPlace, Double longitude,
      Double latitude, String appKey) {
    MultiValueMap<String, String> kv = new LinkedMultiValueMap<String, String>();
    kv.add("orderId", String.valueOf(orderId));
    kv.add("toPlace", toPlace);
    kv.add("longitude", String.valueOf(longitude));
    kv.add("latitude", String.valueOf(latitude));
    kv.add("appKey", appKey);
    String result = postMultiValueMap(buildApi(UPDATE_TOPLACE_V4), kv);
    ResultTransport resultTransport = JSON.parseObject(result, ResultTransport.class);

    return resultTransport;
  }
  
  /**
   * 查询正在执行中订单数量.
   */
  
  public Long countRunning(Long passengerId, String appKey) {
    Long num = 0L;
    try {
      Map<String, String> kv = new HashMap<String, String>();

      kv.put("passengerId", String.valueOf(passengerId));
      kv.put("appKey", appKey);
      kv.put("appId", errandAppId);

      String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);

      kv.put("sign", sign);

      String result = restTemplate.getForObject(buildApi(COUNT_RUNNINGS), String.class, kv);

      JSONObject jo = JSON.parseObject(result);

      if (jo.getIntValue("code") == 0) {
        num = jo.getLongValue("data");
      }
    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
    return num;
  }
  
  /**
   * 根据乘客查询未支付的订单数量.
   */
  
  public Long countNotPayAmounts(Long passengerId, String appKey) {

    Long num = 0L;
    try {
      Map<String, String> kv = new HashMap<String, String>();

      kv.put("passengerId", String.valueOf(passengerId));
      kv.put("appKey", appKey);
      kv.put("appId", errandAppId);

      String sign = SignHelper.sign(SignHelper.buildSignMessage(kv), errandAppKey);

      kv.put("sign", sign);

      String result = restTemplate.getForObject(buildApi(COUNT_NOTPAYAMOUNTS), String.class, kv);

      JSONObject jo = JSON.parseObject(result);

      if (jo.getIntValue("code") == 0) {
        num = jo.getLongValue("data");
      }
    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
    return num;
  }

  public Long countNotFinishedByPassenger(Long passengerId, String appKey) {

    Long num = 0L;
    try {
      Map<String, String> kv = new HashMap<String, String>();

      kv.put("passengerId", String.valueOf(passengerId));
      kv.put("appKey", appKey);


      String result = restTemplate.getForObject(buildApi(COUNT_NOTFINISHEDAMOUNTS), String.class, kv);

      JSONObject jo = JSON.parseObject(result);

      if (jo.getIntValue("code") == 0) {
        num = jo.getLongValue("data");
      }
    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
    return num;
  }
}
